package com.sprouting.metadata.core.model;

import com.sprouting.metadata.core.enums.DatabaseEnum;
import com.sprouting.metadata.core.enums.LetterCaseEnum;

import javax.sql.DataSource;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.logging.Logger;

/**
 * 自定义数据源
 *
 * @author ：LX（长沙麓谷）
 * @date 创建时间： 2022/4/24 10:19
 */
public class SimpleDataSource implements DataSource {

    /**
     * 数据库驱动相关信息
     * @see DatabaseEnum
     */
    private DatabaseEnum databaseEnum;
    /**
     * 数据库链接
     */
    private String url;
    /**
     * 数据库用户
     */
    private String user;
    /**
     * 密码
     */
    private String password;
    /**
     * 数据源
     */
    private DataSource dataSource;


    // --- 自动构建的连接信息
    /**
     * 链接信息-自动构建
     */
    private Connection connection;
    /**
     * 数据库大小写，自动填充
     */
    private LetterCaseEnum letterCaseEnum;



    /**
     * 构造方法- 1
     * 适用于系统已定义了数据源的情况
     * @param databaseEnum 数据源驱动信息
     * @param dataSource 数据源
     */
    public SimpleDataSource(DatabaseEnum databaseEnum, DataSource dataSource){
        this.dataSource = dataSource;
        this.databaseEnum = databaseEnum;

        try {
            Class.forName(databaseEnum.getDriverClass());
            this.connection = this.getConnection();

        } catch (ClassNotFoundException e) {
            throw new RuntimeException("找不到指定的数据库驱动（The specified database driver could not be found）：" + databaseEnum.getDriverClass());
        } catch (SQLException e) {
            throw new RuntimeException("数据库连接获取失败：", e);
        }
    }

    /**
     * 构造方法
     * 适用于全新的完成没有定义数据源的情况
     * @param databaseEnum 数据源驱动信息
     * @param url 数据库链接
     * @param user 用户
     * @param password 密码
     */
    public SimpleDataSource(DatabaseEnum databaseEnum, String url, String user, String password) {
        this.databaseEnum = databaseEnum;
        this.url = url;
        this.user = user;
        this.password = password;
        this.dataSource = this;

        try {
            Class.forName(databaseEnum.getDriverClass());
            this.connection = this.getConnection();

        } catch (ClassNotFoundException e) {
            throw new RuntimeException("找不到指定的数据库驱动（The specified database driver could not be found）：" + databaseEnum.getDriverClass());
        } catch (SQLException e) {
            throw new RuntimeException("数据库连接获取失败：", e);
        }
    }

    /**
     * 获取数据库链接
     * @return
     * @throws SQLException
     */
    @Override
    public Connection getConnection() throws SQLException {
        if (connection != null){
            return connection;
        }

        if (dataSource instanceof SimpleDataSource){
            Connection connection = DriverManager.getConnection(url, user, password);
            this.connection = connection;
            return connection;
        } else {
            Connection connection = dataSource.getConnection();
            this.connection = connection;
            return connection;
        }
    }

    /**
     * 获取数据库连接
     * @param username 数据库连接用户
     * @param password 连接密码
     * @return
     * @throws SQLException
     */
    @Override
    public Connection getConnection(String username, String password) throws SQLException {
        if (dataSource instanceof SimpleDataSource){
            return DriverManager.getConnection(url, user, password);
        } else {
            return dataSource.getConnection();
        }
    }

    @Override
    public <T> T unwrap(Class<T> iface) throws SQLException {
        return null;
    }

    @Override
    public boolean isWrapperFor(Class<?> iface) throws SQLException {
        return false;
    }

    @Override
    public PrintWriter getLogWriter() throws SQLException {
        return null;
    }

    @Override
    public void setLogWriter(PrintWriter out) throws SQLException {

    }

    @Override
    public void setLoginTimeout(int seconds) throws SQLException {

    }

    @Override
    public int getLoginTimeout() throws SQLException {
        return 0;
    }

    @Override
    public Logger getParentLogger() throws SQLFeatureNotSupportedException {
        return null;
    }


    /**
     * get 和 set 方法， 这里不能直接使用 @data 注解
     */

    public DatabaseEnum getDatabaseEnum() {
        return databaseEnum;
    }

    public void setDatabaseEnum(DatabaseEnum databaseEnum) {
        this.databaseEnum = databaseEnum;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String getUser() {
        return user;
    }

    public void setUser(String user) {
        this.user = user;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public DataSource getDataSource() {
        return dataSource;
    }

    public void setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    public void setConnection(Connection connection) {
        this.connection = connection;
    }

    public LetterCaseEnum getLetterCaseEnum() {
        return letterCaseEnum;
    }

    public void setLetterCaseEnum(LetterCaseEnum letterCaseEnum) {
        this.letterCaseEnum = letterCaseEnum;
    }
}
